﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using PatientInformationExtract.MainInterface.Views;
using System.Windows.Input;
using PatientInformationExtract.Components;
using System.Windows;
using System.Collections.ObjectModel;
using PatientInformationExtract.MainInterface.Models;
using System.Windows.Threading;
using PatientInformationExtract.MainInterface.Models.XMLCS;

namespace PatientInformationExtract.MainInterface.ViewModels
{
    public class ExportViewModel : WindowViewModelBase
    {
        private int _exportInterval;
        public int ExportInterval
        {
            get
            {
                return this._exportInterval;
            }
            set
            {
                if (this._exportInterval != value)
                {
                    this._exportInterval = value;
                    base.NotifyPropertyChanged("ExportInterval");
                }
            }
        }

        private bool _isEncoded;
        public bool IsEncoded
        {
            get
            {
                return this._isEncoded;
            }
            set
            {
                if (this._isEncoded != value)
                {
                    this._isEncoded = value;
                    base.NotifyPropertyChanged("IsEncoded");
                }
            }
        }

        private bool _isTranslatedToEnglish;
        public bool IsTranslatedToEnglish
        {
            get { return this._isTranslatedToEnglish; }
            set
            {
                if (this._isTranslatedToEnglish != value)
                {
                    if (value == false)
                    {
                        this.IsUsedTranslator = false;
                    }
                    this._isTranslatedToEnglish = value;
                    base.NotifyPropertyChanged("IsTranslatedToEnglish");
                }
            }
        }

        private bool _isUsedTranslator;
        public bool IsUsedTranslator
        {
            get { return this._isUsedTranslator; }
            set
            {
                if (this._isUsedTranslator != value)
                {
                    this._isUsedTranslator = value;
                    base.NotifyPropertyChanged("IsUseTranslator");
                }
            }
        }

        private bool _isSynonymReplaced;
        public bool IsSynonymReplaced
        {
            get { return this._isSynonymReplaced; }
            set
            {
                if (this._isSynonymReplaced != value)
                {
                    this._isSynonymReplaced = value;
                    base.NotifyPropertyChanged("IsSynonymReplaced");
                }
            }
        }

        private bool _isOpenFileAfterExport;
        public bool IsOpenFileAfterExport
        {
            get { return this._isOpenFileAfterExport; }
            set
            {
                if (this._isOpenFileAfterExport != value)
                {
                    this._isOpenFileAfterExport = value;
                    base.NotifyPropertyChanged("IsOpenFileAfterExport");
                }
            }
        }

        private bool _isParseOptionEnabled;
        public bool IsParseOptionEnabled
        {
            get { return this._isParseOptionEnabled; }
            set
            {
                if (this._isParseOptionEnabled != value)
                {
                    this._isParseOptionEnabled = value;
                    this.IsParsedExamInfo = value;
                    this.IsParsedLabInfo = value;
                    this.IsParsedOrdersInfo = value;
                    this.IsParsedProcessNoteInfo = value;
                    this.IsParsedVitalSignInfo = value;
                    base.NotifyPropertyChanged("IsParseOptionEnabled");
                }
            }
        }

        private bool _isParsedLabInfo;
        public bool IsParsedLabInfo
        {
            get { return this._isParsedLabInfo; }
            set
            {
                if (this._isParsedLabInfo != value)
                {
                    this._isParsedLabInfo = value;
                    base.NotifyPropertyChanged("IsParsedLabInfo");
                }
            }
        }

        private bool _isParsedExamInfo;
        public bool IsParsedExamInfo
        {
            get { return this._isParsedExamInfo; }
            set
            {
                if (this._isParsedExamInfo != value)
                {
                    this._isParsedExamInfo = value;
                    base.NotifyPropertyChanged("IsParsedExamInfo");
                }
            }
        }

        private bool _isParsedOrdersInfo;
        public bool IsParsedOrdersInfo
        {
            get { return this._isParsedOrdersInfo; }
            set
            {
                if (this._isParsedOrdersInfo != value)
                {
                    this._isParsedOrdersInfo = value;
                    base.NotifyPropertyChanged("IsParsedOrdersInfo");
                }
            }
        }

        private bool _isParsedVitalSignInfo;
        public bool IsParsedVitalSignInfo
        {
            get { return this._isParsedVitalSignInfo; }
            set
            {
                if (this._isParsedVitalSignInfo != value)
                {
                    this._isParsedVitalSignInfo = value;
                    base.NotifyPropertyChanged("IsParsedVitalSignInfo");
                }
            }
        }

        private bool _isParsedProcessNoteInfo;
        public bool IsParsedProcessNoteInfo
        {
            get { return this._isParsedProcessNoteInfo; }
            set
            {
                if (this._isParsedProcessNoteInfo != value)
                {
                    this._isParsedProcessNoteInfo = value;
                    base.NotifyPropertyChanged("IsParsedProcessNoteInfo");
                }
            }
        }

        private string _exportPath;
        public string ExportPath
        {
            get
            {
                return this._exportPath;
            }
            set
            {
                if (this._exportPath != value)
                {
                    this._exportPath = value;
                    base.NotifyPropertyChanged("ExportPath");
                }
            }
        }

        private List<string> _exportList;
        public List<string> ExportList
        {
            get
            {
                return this._exportList;
            }
            set
            {
                if (this._exportList != value)
                {
                    this._exportList = value;
                    base.NotifyPropertyChanged("ExportList");
                }
            }
        }

        private int _exportCurrentCount;
        public int ExportCurrentCount
        {
            get
            {
                return this._exportCurrentCount;
            }
            set
            {
                if (this._exportCurrentCount != value)
                {
                    this._exportCurrentCount = value;
                    base.NotifyPropertyChanged("ExportCurrentCount");
                }
            }
        }

        private string _exportStatus;
        public string ExportStatus
        {
            get
            {
                return this._exportStatus;
            }
            set
            {
                if (this._exportStatus != value)
                {
                    this._exportStatus = value;
                    base.NotifyPropertyChanged("ExportStatus");
                }
            }
        }

        public int _exportFoldersCount;
        public int ExportFoldersCount
        {
            get
            {
                return this._exportFoldersCount;
            }
            set
            {
                if (this._exportFoldersCount != value)
                {
                    this._exportFoldersCount = value;
                    base.NotifyPropertyChanged("ExportFoldersCount");
                }
            }
        }

        private MultiTypeValue _exportComponentsState = new MultiTypeValue();
        public MultiTypeValue ExportComponentsState { get { return this._exportComponentsState; } }

        public MultiTypeValue ExportComponentsReversedState { get { return this._exportComponentsState.Reversal(); } }

        private ObservableCollection<PatientListTreeItem> _patientListView;
        public ObservableCollection<PatientListTreeItem> PatientListView
        {
            get
            {
                return this._patientListView;
            }
            set
            {
                if (this._patientListView != value)
                {
                    this._patientListView = value;
                    base.NotifyPropertyChanged("PatientListView");
                }
            }
        }

        private ICommand _exportCommand;
        public ICommand ExportCommand { get { return this._exportCommand; } }

        private ICommand _browseCommand;
        public ICommand BrowseCommand { get { return this._browseCommand; } }

        private ICommand _cancelCommand;
        public ICommand CancelCommand { get { return this._cancelCommand; } }

        private ICommand _selectAllCommand;
        public ICommand SelectAllCommand { get { return this._selectAllCommand; } }

        private ICommand _unselectAllCommand;
        public ICommand UnselectAllCommand { get { return this._unselectAllCommand; } }

        public ExportViewModel(WindowViewModelBase parent, ObservableCollection<PatientListTreeItem> patientListTreeView)
        {
            this._exportCommand = new Command(new Action<object>(this.Export));
            this._browseCommand = new Command(new Action<object>(this.Browse));
            this._cancelCommand = new Command(new Action<object>(this.Cancel));
            this._selectAllCommand = new Command(new Action<object>(this.SelectAll));
            this._unselectAllCommand = new Command(new Action<object>(this.UnselectAll));

            this.PatientListView = patientListTreeView;
            this.ExportList = new List<string>();

            this.ExportPath = @"C:\EventLog\";
            this.IsEncoded = false;
            this.IsSynonymReplaced = false;
            this.IsTranslatedToEnglish = false;
            this.IsOpenFileAfterExport = false;
            this.ExportInterval = 100;

            base._parent = parent;
            WindowInitialize();
            SelectAll(null);
        }

        protected override void WindowInitialize()
        {
            base.WindowInitialize();
            base._window = new ExportWindow();
            base._window.DataContext = this;           
        }

        public void Browse(object o)
        {
            System.Windows.Forms.FolderBrowserDialog folderDlg = new System.Windows.Forms.FolderBrowserDialog();
            System.Windows.Forms.DialogResult result = folderDlg.ShowDialog();
            if (result == System.Windows.Forms.DialogResult.OK)
            {
                ExportPath = folderDlg.SelectedPath + @"EventLog " + DateTime.Now.ToString("yyyy.MM.dd HH.mm.ss") + "\\";
            }
        }

        public void Export(object o)
        {
            this._exportList.Clear();
            foreach (PatientListTreeItem item in this._patientListView)
            {
                if (item.IsChecked != false)
                {
                    if (item.Tag != null)
                    {
                        this._exportList.Add(item.Tag);
                    }
                    else
                    {
                        foreach (PatientListTreeItem it in item.Items)
                        {
                            if (it.IsChecked == true)
                            {
                                this._exportList.Add(it.Tag);
                            }
                        }
                    }
                }
            }
            if (this._exportList.Count > 0)
            {
                base.MultiTypeValueChange(this._exportComponentsState, MultiTypeValue.Command.TrueVisible, "ExportComponentsState");
                base.NotifyPropertyChanged("ExportComponentsReversedState");
                this.ExportFoldersCount = this._exportList.Count;
                ExportModel exportModel = new ExportModel(this._exportList, this._exportInterval, this._exportPath);
                List<Type> parseComponentTypes = new List<Type>();
                if (this.IsParsedExamInfo)
                {
                    parseComponentTypes.Add(typeof(ExamInfo));
                }
                if (this.IsParsedLabInfo)
                {
                    parseComponentTypes.Add(typeof(LabInfo));
                }
                if (this.IsParsedOrdersInfo)
                {
                    parseComponentTypes.Add(typeof(OrdersInfo));
                }
                if (this.IsParsedProcessNoteInfo)
                {
                    parseComponentTypes.Add(typeof(ProcessNoteInfo));
                }
                if (this.IsParsedVitalSignInfo)
                {
                    parseComponentTypes.Add(typeof(VitalSignInfo));
                }
                exportModel.Export(this.IsOpenFileAfterExport, this.IsEncoded, this.IsTranslatedToEnglish, this.IsSynonymReplaced, this.IsUsedTranslator, parseComponentTypes);
                exportModel.ExportStatusUpdateEvent += new ExportModel.ExportStatusUpdateHandler(ExportStatusUpdate);
                exportModel.ExportFinishedEvent += new ExportModel.ExportFinishedHandler(ExportFinished);
            }
            else
            {
                MessageBox.Show("Please select at least one patient folder.");
            }
        }

        private void ExportFinished(TimeSpan consumingTime)
        {
            base.MultiTypeValueChange(this._exportComponentsState, MultiTypeValue.Command.FalseHidden, "ExportComponentsState");
            base.NotifyPropertyChanged("ExportComponentsReversedState");
            MessageBox.Show("Exporting finished, uses " + consumingTime.ToString());
        }

        private void ExportStatusUpdate(int currentCount, string nextFolderPath)
        {
            this.ExportCurrentCount = currentCount;
            if (nextFolderPath.Length > 20)
            {
                this.ExportStatus = String.Format("{0:P}", (double)this.ExportCurrentCount / this.ExportFoldersCount) + ", Extracting " + nextFolderPath.Substring(0, 20) + "...";
            }
            else
            {
                this.ExportStatus = String.Format("{0:P}", (double)this.ExportCurrentCount / this.ExportFoldersCount) + ", Extracting " + nextFolderPath;
            }
        }

        public void Cancel(object o)
        {
            base._window.Close();
        }

        public void SelectAll(object o)
        {
            foreach (PatientListTreeItem item in this._patientListView)
            {
                item.IsChecked = true;
            }
        }

        public void UnselectAll(object o)
        {
            foreach (PatientListTreeItem item in this._patientListView)
            {
                item.IsChecked = false;
            }
        }
    }
}
